package com.dnxh.service.impl;


import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.dnxh.config.exception.CustomException;
import com.dnxh.constant.CommonConstant;
import com.dnxh.constant.CustomResult;
import com.dnxh.constant.EmailEnum;
import com.dnxh.entity.BasicInfo;
import com.dnxh.entity.BasicMeeting;
import com.dnxh.entity.Meeting;
import com.dnxh.entity.common.PageContext;
import com.dnxh.entity.common.PageRequest;
import com.dnxh.entity.request.CreateBasicInfoRequest;
import com.dnxh.entity.request.SearchBasicInfoRequest;
import com.dnxh.mapper.BasicInfoMapper;
import com.dnxh.service.BasicInfoService;
import com.dnxh.service.BasicMeetingService;
import com.dnxh.service.DepartmentService;
import com.dnxh.service.MeetingService;
import com.dnxh.util.LogUtil;
import com.dnxh.util.RedisUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author zhiqiu
 * @since 2022-04-06
 */
@Slf4j
@Service
public class BasicInfoServiceImpl extends ServiceImpl<BasicInfoMapper, BasicInfo> implements BasicInfoService {
	
	@Resource
	private RedisUtil           redisUtil;
	@Resource
	private DepartmentService   departmentService;
	@Resource
	private BasicInfoMapper     basicInfoMapper;
	@Resource
	private HttpServletRequest  httpServletRequest;
	@Lazy
	@Resource
	private LogUtil             logUtil;
	@Resource
	private BasicMeetingService basicMeetingService;
	@Lazy
	@Resource
	private MeetingService metingService;
	
	@Transactional (rollbackFor = Exception.class)
	@Override
	public void create (CreateBasicInfoRequest request) {
		Long id = IdUtil.getSnowflakeNextId ();
		List<BasicInfo> list = list ();
		String key = CommonConstant.SEND_MESSAGE + EmailEnum.REGISTER.name () + StrUtil.COLON + request.getEmail ();
		String code = redisUtil.get (key) + StrUtil.EMPTY;
		if (! code.equals (request.getCode ())) {
			throw new CustomException ("校验码错误!");
		}
		redisUtil.del (key);
		if (request.getUrlId () != 0) {
			Map<String, BasicInfo> map = list
					.stream ()
					.collect (Collectors.toMap (BasicInfo::getEmail, e -> e, (key1, key2) -> key1));
			long infoId = id;
			if (map.containsKey (request.getEmail ())) {
				infoId = map.get (request.getEmail ()).getId ();
			}
			if (metingService.getOne (Wrappers.<Meeting>lambdaQuery ()
					.select (Meeting::getId)
					.eq (Meeting::getId,request.getUrlId ())) == null){
				throw new CustomException ("该会议/比赛号码不存在!");
			}
			if (basicMeetingService.getOne (Wrappers.<BasicMeeting>lambdaQuery ()
					.select (BasicMeeting::getId)
					.eq (BasicMeeting::getMeetingId,request.getUrlId ())
					.eq (BasicMeeting::getBasicId,infoId)) != null){
				throw new CustomException ("您已报名参加该会议/比赛");
			}
			basicMeetingService.save (new BasicMeeting ()
					.setId (IdUtil.getSnowflakeNextId ())
					.setBasicId (infoId)
					.setMeetingId (request.getUrlId ())
					.setCreateTime (new Date ()));
		} else {
			List<String> qqList = list
					.stream ()
					.map (BasicInfo::getQqInfo)
					.collect (Collectors.toList ());
			if (qqList.contains (request.getQqInfo ().trim ())) {
				throw new CustomException ("QQ信息已存在");
			}
			List<String> emailList = list
					.stream ()
					.map (BasicInfo::getEmail)
					.collect (Collectors.toList ());
			if (emailList.contains (request.getEmail ().trim ())) {
				throw new CustomException ("邮箱信息已存在!");
			}
			List<String> phoneList = list
					.stream ()
					.map (BasicInfo::getPhone)
					.collect (Collectors.toList ());
			if (phoneList.contains (request.getPhone ().trim ())) {
				throw new CustomException ("电话号码已存在!");
			}
		}
		BasicInfo basicInfo = BeanUtil.toBean (request, BasicInfo.class);
		basicInfo.setId (id);
		basicInfo.setCreateTime (new Date ());
		save (basicInfo);
	}
	
	@Override
	public CustomResult confirm (Long id) {
		BasicInfo basicInfo = getOne (Wrappers.<BasicInfo>lambdaQuery ()
				.select (BasicInfo::getIsEnable)
				.eq (BasicInfo::getId, id));
		if (basicInfo.getIsEnable () != 0) {
			update (Wrappers.<BasicInfo>lambdaUpdate ()
					.set (BasicInfo::getIsEnable, 0)
					.eq (BasicInfo::getId, id));
		} else {
			update (Wrappers.<BasicInfo>lambdaUpdate ()
					.set (BasicInfo::getIsEnable, 1)
					.eq (BasicInfo::getId, id));
		}
		logUtil.recordOperation (httpServletRequest, id, basicInfo.getIsEnable () != 0 ? 0 : 1);
		return CustomResult.success ();
	}
	
	@Override
	public CustomResult searchInfo (SearchBasicInfoRequest req) {
		if (req.getPageSize () == - 1) {
			req.setPageSize ((int) count ());
		}
		IPage<BasicInfo> iPage = new Page<BasicInfo> ()
				.setSize (req.getPageSize ())
				.setCurrent (req.getPageNum ());
		List<BasicInfo> list = basicInfoMapper.searchInfoByCondition (iPage,
				req.getNickName (), req.getQq (), req.getPhone (), req.getDepartment ());
		return CustomResult.success (new PageContext<BasicInfo> ()
				.setCount (iPage.getTotal ())
				.setList (list));
	}
	
	@Override
	public CustomResult searchDepartment (PageRequest req) {
		return CustomResult.success (departmentService.search (req));
	}
	
	@Override
	public List<BasicInfo> searchByGrade (List<String> grades) {
		return CollUtil.isEmpty (grades) ? Collections.emptyList () : baseMapper.searchInfoByGrade (grades);
	}
	
	@Override
	public List<BasicInfo> searchByDepartment (List<String> departments) {
		return CollUtil.isEmpty (departments) ? Collections.emptyList () :
				baseMapper.searchInfoByDepartment (departments);
	}
}